<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Five in a row</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            html,body{
                height: 100%;
                width: 100%;
                margin: 0;
                padding: 0;
            }
            body{
                background-color:#FCF8EF!important;
                overflow:hidden;
                position: relative;
            }
            canvas{
                background-color:#FCF8EF;
                width:100%;
                height:100%
            }
            div#myContainer{
                position: absolute;
                width: 100%;
                height:100%;
            }
            div#slider{
                position: absolute;
                background-color: #f1e7d0;
                top: 100px;
                height: 800px;
                left: 4%;
                width: 20%;
                border:1px solid darkslategray;
                box-shadow: darkgrey 10px 10px 30px 5px 
            }
        </style>
        <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
        <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    </head>
    <body>
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                        <h4 class="modal-title" id="myModalLabel">提示  <strong id="counter"></strong></h4>
                    </div>
                    <div class="modal-body">在这里添加一些文本</div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-primary" data-dismiss="modal">关闭</button>
                    </div>
                </div>
            </div>
        </div>
        <script src="Three.js"></script>
        <script src="TrackballControls.js"></script>

        <div id="myContainer">

        </div>

        <div id="slider">
            <div class="container" style="width:100%">
                <form class="form-horizontal" role="form" style="margin-top: 60px;">
                    <div class="form-group">
                        <label class="col-sm-12">我的身份: <span id="actor">暂无</span></label>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-12">房间号: <span id="zoom" title="点击复制">暂无</span> <span onclick="copy()"> 复制</span></label>
                    </div>
                    <div class="form-group">
                    </div>
                    <div class="form-group">
                        <label class="col-sm-12">棋手</label>
                    </div>
                    <div class="form-group text-center">
                        <label class="col-sm-6 col-md-6" id="black" data="黑棋">黑棋</label>
                        <label class="col-sm-6 col-md-6" id="white" data="白棋">白棋</label>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-12">旁观人数: <span id="number">0</span></label>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-12"><a href="./index.html">返回主页</a></label>
                    </div>
                </form>
            </div>

        </div>

        <script>
            function setCookie(name,value,time=7){
                var exp = new Date();
                exp.setTime(exp.getTime() + time*24*60*60*1000);
                document.cookie = name + "="+ encodeURIComponent(value) +";expires="+ exp.toUTCString();
            }
            function copy(){
                let zoom = $("#zoom").html();
                const input = document.createElement('input');
                    document.body.appendChild(input);
                    input.setAttribute('value', zoom);
                    input.select();
                    if (document.execCommand('copy')) {
                        document.execCommand('copy');
                        showMessage('复制成功',1,1000);
                    }
                document.body.removeChild(input);
            }

            function getCookie(name) {
                var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
                if(arr != null)
                    return decodeURIComponent(arr[2]);
                return null;
            }

            var h;
            function GetQueryString(name){
                var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
                var r = window.location.search.substr(1).match(reg);
                if(r!=null)
                    return  unescape(r[2]);
                return null;
            }
            function setZoom(zoom){
                $("#zoom").html(zoom);
            }
            function setActor(actor){
                let actors = ['黑棋', '白棋', '旁观者'];
                $("#actor").html(actors[actor]);
            }
            function setNumber(number){
                if(number > 2){
                    number = number -2;
                } else {
                    number = 0;
                }
                $("#number").html(number);
            }
            function setGo(toGo){
                let qs = ["black", "white"];
                if(h){
                    clearInterval(h);
                }
                $("#" + qs[ 1- toGo]).html($("#" + qs[ 1- toGo]).attr("data"));
                h = setInterval(function(){
                    if($("#" + qs[toGo]).html() !== ""){
                        $("#" + qs[toGo]).html("")
                    } else {
                        $("#" + qs[toGo]).html($("#" + qs[toGo]).attr("data"));
                    }
                },500);
            }
            function setOver(){
                clearInterval(h);
            }



            var zoom = "";
            function showMessage(message, type = 1, time=2000, wait=0) {
                let ele = $("#myModal .modal-body");
                $(ele).html(message);
                let color;
                if(type === 1 ) {
                    color = "#3c763d"; //成功
                } else {
                    color = "#8a6d3b"; // 警告
                }
                $(ele).css("color",color);
                $("#myModal").modal('show');
                if(!wait){ // 不等待
                    setTimeout(function () {
                        $("#myModal").modal('hide');
                    },time);
                    let count = time / 1000;
                    $("#counter").html(count);
                    let h = setInterval(function () {
                        count--;
                        if(count >= 0){
                            $("#counter").html(count)
                        } else {
                            clearInterval(h);
                        }
                    },1000);
                }
            }
            let ele = document.getElementById("myContainer");

            var INTERSECTED,geometry,line,sphere,light,blackwhite,x,y,z,towalk=false;
            var projector = new THREE.Projector();
            var renderer=new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            ele.appendChild(renderer.domElement);

            var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,3000);
            camera.position.z=1200;
            var controls= new THREE.TrackballControls(camera);
            controls.noPan=true;
            controls.minDistance=10;
            controls.maxDistance=1500;
            var scene=new THREE.Scene();
            var group=new THREE.Object3D();
            var tobeupdate=new THREE.Object3D();
            scene.add(group);
            scene.add(tobeupdate);
            light=new THREE.DirectionalLight(0xffffff,0.8,0);
            light.position.set(200,200,200);
            scene.add(light);
            light=new THREE.DirectionalLight(0xffffff,0.8,0);
            light.position.set(-500,200,200);
            scene.add(light);
            light=new THREE.DirectionalLight(0xffffff,0.8,0);
            light.position.set(200,-500,200);
            scene.add(light);
            light=new THREE.DirectionalLight(0xffffff,0.8,0);
            light.position.set(200,200,-500);
            scene.add(light);
            var material=new THREE.LineBasicMaterial({color:0xA0522D,opacity:1});
            for (var i=-3;i<=3;i++) {
                for (var j=-3;j<=3;j++) {
                    geometry=new THREE.Geometry();
                    geometry.vertices.push(new THREE.Vector3(100*i,100*j,-300));
                    geometry.vertices.push(new THREE.Vector3(100*i,100*j,300));
                    line=new THREE.Line(geometry,material);
                    scene.add(line);
                }
            }
            for (var i=-3;i<=3;i++) {
                for (var k=-3;k<=3;k++) {
                    geometry=new THREE.Geometry();
                    geometry.vertices.push(new THREE.Vector3(100*i,-300,100*k));
                    geometry.vertices.push(new THREE.Vector3(100*i,300,100*k));
                    line=new THREE.Line(geometry,material);
                    scene.add(line);
                }
            }
            for (var j=-3;j<=3;j++) {
                for (var k=-3;k<=3;k++) {
                    geometry=new THREE.Geometry();
                    geometry.vertices.push(new THREE.Vector3(-300,100*j,100*k));
                    geometry.vertices.push(new THREE.Vector3(300,100*j,100*k));
                    line=new THREE.Line(geometry,material);
                    scene.add(line);
                }
            }
            for (var i=-3;i<=3;i++) {
                for (var j=-3;j<=3;j++) {
                    for (var k=-3;k<=3;k++) {
                        sphere=new THREE.Mesh(new THREE.SphereGeometry(2,16,16),new THREE.MeshLambertMaterial({color:0xA0522D}));
                        sphere.position.set(100*i,100*j,100*k);
                        group.add(sphere);
                    }
                }
            }

            function Init() {
                var todel=tobeupdate.children;
                for (var i=todel.length-1;i>=0;i--)
                    tobeupdate.remove(todel[i]);
            }

            var connection=new WebSocket('ws://49.233.221.184:8081');
            connection.onopen=function(){
                if(getCookie('zoomOrder') == null){
                    showMessage('无法初始化房间，请返回大厅', 0, 2000, 1);
                    return;
                }
                let str = getCookie("zoomOrder");
                try {
                    if (typeof JSON.parse(str) !== "object") {
                        showMessage('无法初始化房间，请返回大厅', 0, 2000, 1);
                        return;
                    }
                } catch(e) {
                    showMessage('无法初始化房间，请返回大厅', 0, 2000, 1);
                        return;
                }
                let json = JSON.parse(str);
                if(!json.order){
                    showMessage('无法初始化房间，请返回大厅', 0, 2000, 1);
                    return;
                }
                if(json.order === 'create'){ // 创建房价
                    connection.send(JSON.stringify({order:'create'}));
                } else if(json.order === 'enter' && json.data){ // 进入房间
                    zoom = json.data;
                    connection.send(JSON.stringify({order: 'enter', data: json.data }))
                    setZoom(zoom);
                }
            };
            connection.onerror=function(error){
                showMessage("Can't connect to the server .", 0, 2000,1);
            };
            connection.onmessage=function(message){
                var json=JSON.parse(message.data);
                console.log(json);
                if (json.type=='ctrl') // 控制信息
                {
                    switch(json.data)
                    {
                        case -1:
                            showMessage("无法进入房间，不存在房间" + zoom, 0, 3000);
                            break;
                        case -2:
                            showMessage("您已经在房间中，房间" + zoom, 0, 3000);
                            break;
                        case -3:
                            showMessage("您无法执行落子", 0, 3000);
                            break;
                        case -4:
                            setOver();
                            showMessage("游戏已经结束，请返回大厅", 1, 3000,1);
                            break;
                        case 0:
                            blackwhite=0;
                            setActor(0);
                            showMessage("游戏正式开始，您是黑棋选手，请开始", 1, 3000,1);
                            break;
                        case 1:
                            blackwhite=1;
                            setActor(1);
                            showMessage("游戏正式开始，您是白棋选手", 1, 3000,1);
                            break;
                        case 2:
                            blackwhite=2;
                            setActor(2);
                            showMessage("游戏已经开始，您可以参与旁观", 1, 3000,1);
                            break;
                        case 3:
                            towalk = true;
                            break;
                        case 4:
                            setOver();
                            showMessage("黑棋选手离开房间，游戏结束", 1, 3000,1);
                            break;
                        case 5:
                            setOver();
                            showMessage("白棋选手离开房间，游戏结束", 1, 3000,1);
                            break;
                        case 6:
                            setOver();
                            showMessage("平局，游戏结束", 1, 3000,1);
                            break;
                        case 7:
                            setOver();
                            showMessage("白棋选手获胜，游戏结束", 1, 3000,1);
                            break;
                        case 8:
                            setOver();
                            showMessage("黑棋选手获胜，游戏结束", 1, 3000,1);
                            break;

                    }
                }
                else if (json.type=='step') // 别人走了一步后，渲染，判断是否自己可以走
                {
                    var step=json.data;
                    if (step.color) // color为一表示白棋
                        sphere=new THREE.Mesh(new THREE.SphereGeometry(40,32,32),new THREE.MeshLambertMaterial({color:0xffffff}));
                    else 
                        sphere=new THREE.Mesh(new THREE.SphereGeometry(40,32,32),new THREE.MeshLambertMaterial({color:0x363636}));
                    sphere.position.set(100*(step.x-3),100*(step.y-3),100*(step.z-3));
                    tobeupdate.add(sphere);
                    setGo(1 - step.color);
                }
                else if (json.type=='board') // 棋盘信息
                {
                        for (var i=-3;i<=3;i++)
                            for (var j=-3;j<=3;j++)
                                for (var k=-3;k<=3;k++)
                                    if (json.data[i+3][j+3][k+3])
                                    {
                                        if (json.data[i+3][j+3][k+3]==1)  // 白球
                                            sphere=new THREE.Mesh(new THREE.SphereGeometry(40,32,32),new THREE.MeshLambertMaterial({color:0xffffff}));
                                        else // 其他非0数字黑球
                                            sphere=new THREE.Mesh(new THREE.SphereGeometry(40,32,32),new THREE.MeshLambertMaterial({color:0x363636}));
                                        sphere.position.set(100*i,100*j,100*k);
                                        tobeupdate.add(sphere);
                                    }
                } else if(json.type=='number'){
                    setNumber(json.data);
                    console.log('人数' + json.data);
                } else if(json.type=='zoom'){
                    setZoom(json.data);
                    zoom = json.data;
                    showMessage('您已成功创建房间，房间号为' + json.data + '。 快邀请小伙伴们加入吧！',1,2000,1);
                }
            }

            ele.addEventListener('mousemove',onDocumentMouseMove,false);
            ele.addEventListener('mousedown',onDocumentMouseDown,false);

            animateScene();
            function highlight(intersect){
                intersect.material.color.setHex(0xe60f1a);
                intersect.material.emissive.setHex(0xe60f1a);

            }
            function ordinary(intersect){
                intersect.material.color.setHex(0xA0522D);
                intersect.material.emissive.setHex(0x000000);
            }
            function onDocumentMouseMove(event) {
                event.preventDefault();
                var vector=new THREE.Vector3((event.clientX/window.innerWidth)*2-1,-(event.clientY/window.innerHeight)*2+1,0.5);
                projector.unprojectVector(vector,camera);
                var ray=new THREE.Ray(camera.position,vector.subSelf(camera.position).normalize());
                var intersects=ray.intersectObjects(group.children);
                if (intersects.length>0) {
                    if (INTERSECTED!=intersects[0].object) {
                        if (INTERSECTED) ordinary(INTERSECTED);
                        INTERSECTED=intersects[0].object;
                        highlight(INTERSECTED)
                    }
                } else {
                    if (INTERSECTED) ordinary(INTERSECTED);
                    INTERSECTED=null;
                }
            }

            function onDocumentMouseDown(event) {
                event.preventDefault();
                var vector=new THREE.Vector3((event.clientX/window.innerWidth)*2-1,-(event.clientY/window.innerHeight)*2+1,0.5);
                projector.unprojectVector(vector,camera);
                var ray=new THREE.Ray(camera.position,vector.subSelf(camera.position).normalize());
                var intersects=ray.intersectObjects(group.children);
                if (towalk&&intersects.length>0) {
                    x=intersects[0].object.position.x/100+3,
                    y=intersects[0].object.position.y/100+3,
                    z=intersects[0].object.position.z/100+3;
                    connection.send(JSON.stringify({order:'play',data:[x,y,z]}));
                    towalk=false;
                }
            }

            function animateScene() {
                controls.update();
                requestAnimationFrame(animateScene);
                renderer.render(scene,camera);
            }
            window.onbeforeunload=function(){
                if(blackwhite === 0 || blackwhite === 1){
                    return "棋手离开会直接导致游戏结束！";
                } else {
                    return "您真的要离开吗？";
                }
            }
        </script>
    </body>
</html>